<script setup>
import { reactive, ref, onMounted, getCurrentInstance, nextTick, onUnmounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import MainContent from '@/components/mainContent.vue'
import path from "path-browserify";
// 引入 Lightbox 组件
import Lightbox from 'vue-easy-lightbox';

const { proxy: { $http } } = getCurrentInstance()
const route = useRoute()
const router = useRouter()

// 缓存键名
const CACHE_KEY = 'studentFeedback_PersistentData';

// WebSocket 相关状态
const ws = ref(null)
const isWsConnected = ref(false)
const reconnectTimer = ref(null)
// 新增：心跳超时计时器（检测后端是否按时发心跳）
const heartbeatTimeoutTimer = ref(null)
// 新增：心跳配置（与后端完全对齐）
const HEARTBEAT_CONFIG = {
  TIMEOUT: 55 * 1000, // 前端超时检测（比后端60秒短，避免误判）
  RESPONSE_MSG: JSON.stringify({ type: "HEARTBEAT_RESPONSE" }), // 心跳响应格式
  REQUEST_TYPE: "HEARTBEAT_REQUEST" // 后端心跳请求标识
};
const wsUrl = path.join(import.meta.env.BASE_URL, import.meta.env.DEV ? "wss://service.neucityai.com:30080/xjwxx/xjwxx-websocket" : "wss://http://192.168.1.19:8031/xjwxx/xjwxx-websocket") //'wss://service.neucityai.com:30080/xjwxx/xjwxx-websocket';
const wsTopic = '/topic/school/student';

// 核心数据定义（含弹框状态）
const feedbackList = ref([])
const submittedCount = ref(0)

// 详情弹框状态
const dialogState = reactive({
  isShow: false,
  currentStudent: null,
});

// 图片预览相关状态
const lightboxState = reactive({
  isShowLightbox: false, // 是否显示图片预览
  currentImgIndex: 0, // 当前预览图片的索引
  imgs: [], // 要预览的图片数组
});

// ---------------------- 新增：倒计时状态 ----------------------
const countdown = reactive({
  total: 300, // 总倒计时秒数（300秒）
  remaining: 300, // 剩余秒数
  timer: null // 定时器实例
});
// ---------------------- 新增结束 ----------------------

// 从 localStorage 读取缓存数据
const getCacheData = () => {
  try {
    const cacheStr = localStorage.getItem(CACHE_KEY);
    if (cacheStr) {
      const cacheData = JSON.parse(cacheStr);
      if (Array.isArray(cacheData)) {
        return cacheData.filter(item =>
            item.id && item.mainImg && Array.isArray(item.subImgs) && item.count !== undefined
        );
      }
    }
  } catch (err) {
    console.error('读取反馈数据缓存失败：', err);
    localStorage.removeItem(CACHE_KEY);
  }
  return [];
};

// 将当前数据写入 localStorage 缓存
const setCacheData = (data) => {
  try {
    const validData = data.filter(item =>
        item.id && item.mainImg && Array.isArray(item.subImgs) && item.count !== undefined
    );
    localStorage.setItem(CACHE_KEY, JSON.stringify(validData));
    console.log(`反馈数据缓存更新：共 ${validData.length} 条有效数据`);
  } catch (err) {
    console.error('写入反馈数据缓存失败：', err);
  }
};

// 打开详情弹框
const openDialog = (student) => {
  dialogState.currentStudent = student;
  dialogState.isShow = true;
  document.body.style.overflow = 'hidden';
};

// 关闭详情弹框
const closeDialog = () => {
  dialogState.isShow = false;
  dialogState.currentStudent = null;
  document.body.style.overflow = '';
  // 关闭图片预览
  lightboxState.isShowLightbox = false;
};

// 打开图片预览
const openLightbox = (index) => {
  // 组装要预览的图片数组，包含主图和子图
  lightboxState.imgs = [dialogState.currentStudent.mainImg, ...dialogState.currentStudent.subImgs];
  lightboxState.currentImgIndex = index;
  lightboxState.isShowLightbox = true;
};

const closeLightbox = () => {
  console.log('关闭图片预览');
  lightboxState.isShowLightbox = false;
};

// ---------------------- 新增：倒计时方法 ----------------------
// 启动倒计时
const startCountdown = () => {
  // 清除已有定时器，避免重复计时
  if (countdown.timer) clearInterval(countdown.timer);
  // 每秒更新剩余秒数
  countdown.timer = setInterval(() => {
    if (countdown.remaining > 0) {
      countdown.remaining--;
    } else {
      // 倒计时结束：清除定时器（可按需添加结束逻辑，如刷新/跳转）
      clearInterval(countdown.timer);
      countdown.timer = null;
    }
  }, 1000);
};

// 停止倒计时（页面卸载时调用）
const stopCountdown = () => {
  if (countdown.timer) {
    clearInterval(countdown.timer);
    countdown.timer = null;
  }
};

// 格式化倒计时显示（XXs）
const formatTime = (seconds) => `${seconds}s`;
// ---------------------- 新增结束 ----------------------

// 监听 feedbackList 变化：实时更新已提交人数 + 同步缓存
watch(feedbackList, (newList) => {
  submittedCount.value = newList.filter(item => item.id).length;
  setCacheData(newList);
}, { deep: true });

// 收到后端任何消息时调用，重置超时计时器
const resetHeartbeatTimeout = () => {
  if (heartbeatTimeoutTimer.value) {
    clearTimeout(heartbeatTimeoutTimer.value);
  }
  // 超时后判定连接异常，触发重连
  heartbeatTimeoutTimer.value = setTimeout(() => {
    console.error('WebSocket心跳超时，触发重连');
    if (ws.value) {
      ws.value.close(999, '心跳超时');
    }
    triggerReconnect();
  }, HEARTBEAT_CONFIG.TIMEOUT);
};

// 初始化 WebSocket 连接
const initWebSocket = () => {
  if (ws.value && isWsConnected.value) return;
  try {
    ws.value = new WebSocket(wsUrl);

    ws.value.onopen = () => {
      isWsConnected.value = true;
      console.log('WebSocket连接成功，开始监听标注消息');
      // 新增：连接成功后启动心跳超时检测
      resetHeartbeatTimeout();
      sendSubscribeMessage();
    };

    ws.value.onmessage = (event) => {
      try {
        // 新增：收到任何消息，先重置心跳超时计时器
        resetHeartbeatTimeout();
        const messageData = JSON.parse(event.data);
        // 新增：判断是否为后端心跳请求，是则回复响应（不干扰业务逻辑）
        if (messageData.type === HEARTBEAT_CONFIG.REQUEST_TYPE) {
          console.log('收到后端心跳请求，回复响应');
          ws.value.send(HEARTBEAT_CONFIG.RESPONSE_MSG);
          return;
        }
        const outerData = messageData.data;

        if (outerData?.type === 'commit' && outerData?.data?.type === 'img') {
          const realData = outerData.data.content;
          console.log('收到学生反馈数据：', realData);
          handleRealFeedbackData(realData);
        }
      } catch (err) {
        console.error('WebSocket消息解析失败：', err);
      }
    };

    ws.value.onerror = (error) => {
      isWsConnected.value = false;
      console.error('WebSocket错误：', error);
      if (heartbeatTimeoutTimer.value) clearTimeout(heartbeatTimeoutTimer.value);
      triggerReconnect();
    };

    ws.value.onclose = (event) => {
      isWsConnected.value = false;
      if (heartbeatTimeoutTimer.value) clearTimeout(heartbeatTimeoutTimer.value);
      if (event.code !== 1000) {
        console.error(`WebSocket关闭（状态码：${event.code}），正在重连...`);
        triggerReconnect();
      }
    };
  } catch (err) {
    console.error('WebSocket初始化失败：', err);
  }
};

// 发送WebSocket订阅请求
const sendSubscribeMessage = () => {
  if (!ws.value || !isWsConnected.value) return;
  const subscribeMsg = {
    command: 'SUBSCRIBE',
    destination: wsTopic
  };
  try {
    ws.value.send(JSON.stringify(subscribeMsg));
    console.log('已发送订阅请求：', subscribeMsg);
  } catch (err) {
    console.error('订阅消息发送失败：', err);
  }
};

// 处理真实反馈数据（去重+格式转换）
const handleRealFeedbackData = (realData) => {
  const { student: studentId, images, text } = realData;
  if (!studentId || !images?.length) return;

  const mainImg = images[0];
  const subImgs = images.slice(1);
  const imgCount = images.length;

  const existingIndex = feedbackList.value.findIndex(item => item.id === studentId);
  if (existingIndex > -1) {
    feedbackList.value[existingIndex] = {
      ...feedbackList.value[existingIndex],
      mainImg,
      subImgs,
      count: imgCount,
      description: text // 存储学生描述
    };
  } else {
    feedbackList.value.push({
      id: studentId,
      mainImg,
      subImgs,
      count: imgCount,
      description: text // 存储学生描述
    });
  }
};

// WebSocket 重连逻辑
const triggerReconnect = () => {
  if (reconnectTimer.value) clearTimeout(reconnectTimer.value);
  reconnectTimer.value = setTimeout(() => {
    console.log('尝试重新连接WebSocket...');
    initWebSocket();
  }, 3000);
};

// 生命周期钩子（优先加载缓存 + 启动倒计时）
onMounted(async () => {
  const cachedData = getCacheData();
  if (cachedData.length > 0) {
    feedbackList.value = cachedData;
  }
  initWebSocket();
  // ---------------------- 新增：启动倒计时 ----------------------
  startCountdown();
  // ---------------------- 新增结束 ----------------------
  await nextTick();
});

// 页面卸载时：兜底更新缓存 + 停止倒计时
onUnmounted(() => {
  if (ws.value) {
    ws.value.close(1000, '页面关闭，主动断开连接');
    ws.value = null;
  }
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
  }
  // 新增：页面卸载时清除心跳超时计时器
  if (heartbeatTimeoutTimer.value) {
    clearTimeout(heartbeatTimeoutTimer.value);
  }
  setCacheData(feedbackList.value);
  if (dialogState.isShow) {
    closeDialog();
  }
  // ---------------------- 新增：停止倒计时 ----------------------
  stopCountdown();
  // ---------------------- 新增结束 ----------------------
});
</script>
<template>
  <MainContent contentWidth="90%"  padding="0">
    <template #content>
      <div class="content-layout">
        <!-- 顶部统计栏 -->
        <div class="top-bar">
          <div class="submitted">已提交 <span class="count">{{ submittedCount }}</span> 人</div>
          <div class="title-wrapper">
            <span class="line"></span>
            <span class="title">学生反馈</span>
            <span class="line"></span>
          </div>
          <!-- 倒计时：绑定新增的格式化时间 -->
          <div class="countdown">倒计时：<span class="time">{{ formatTime(countdown.remaining) }}</span></div>
        </div>

        <!-- 卡片列表容器 -->
        <div class="card-container">
          <div class="card-grid">
            <div class="empty-tip" v-if="feedbackList.length === 0">
              暂无学生反馈数据
            </div>

            <!-- 学生反馈卡片（点击打开详情弹框） -->
            <div class="feedback-card" v-for="student in feedbackList" :key="student.id" @click="openDialog(student)">
              <!-- 主图 -->
              <img
                  :src="student.mainImg"
                  alt="学生反馈主图"
                  class="main-img"
                  loading="lazy"
                  @error="(e) => e.target.src = 'https://picsum.photos/200/150?fallback'"
              />
              <!-- 子图 -->
              <div class="sub-imgs" v-if="student.subImgs.length">
                <img
                    v-for="(subImg, idx) in student.subImgs"
                    :key="idx"
                    :src="subImg"
                    alt="学生反馈子图"
                    class="sub-img"
                    loading="lazy"
                    @error="(e) => e.target.src = 'https://picsum.photos/60/40?fallback'"
                />
              </div>
              <!-- 学号 -->
              <div class="card-footer">
                <span class="student-id">{{ student.id }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
  </MainContent>

  <!-- 详情弹框 -->
  <div class="student-dialog" v-if="dialogState.isShow">
    <!-- 遮罩层（点击关闭弹框） -->
    <div class="dialog-mask" @click="closeDialog"></div>
    <!-- 弹框内容 -->
    <div class="dialog-content">
      <div class="dialog-header">
        <h3>{{ dialogState.currentStudent?.id }}号学生详情查看</h3>
        <button class="close-btn" @click="closeDialog">
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            <path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
          </svg>
        </button>
      </div>
      <div class="dialog-body">
        <!-- 学生描述 -->
        <div class="item-group">
          <span class="label">
            <img width="110px" src="@/assets/img/teachTextDes.png">
          </span>
          <span class="value">{{ dialogState.currentStudent?.description || '暂无描述' }}</span>
        </div>
        <!-- AI图片生成 -->
        <div class="item-group">
          <span class="label">
            <img width="110px" src="@/assets/img/teachAiImg.png"></img>
          </span>
          <div class="images-group">
            <img
                v-for="(img, idx) in [dialogState.currentStudent?.mainImg, ...dialogState.currentStudent?.subImgs]"
                :key="idx"
                :src="img"
                alt="AI生成图片"
                class="ai-img"
                @error="(e) => e.target.src = 'https://picsum.photos/300/200?fallback'"
                @click="openLightbox(idx)"
            />
          </div>
        </div>
      </div>
      <div class="dialog-footer">
        <button class="close-button" @click="closeDialog">关闭</button>
      </div>
    </div>
  </div>

  <!-- 修改 Lightbox 组件，添加 onClose 事件处理 -->
  <Lightbox
      :visible="lightboxState.isShowLightbox"
      :imgs="lightboxState.imgs"
      :index="lightboxState.currentImgIndex"
      @click="closeLightbox"
  ></Lightbox>
</template>

<style scoped lang='scss'>
// 重置默认样式
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

// 核心布局
.content-layout {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: calc(100vh - 180px);
  border-radius: 16px;
  padding: 20px;

  @media (min-width: 768px) and (max-width: 1024px) {
    padding: 25px;
    max-height: calc(100vh - 200px);
  }

  // @media (min-width: 1024px) {
  //   padding: 30px;
  //   max-height: calc(100vh - 220px);
  // }
}

// 顶部统计栏
.top-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-radius: 8px;
  background-color: #ffffff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  flex-wrap: wrap;
  gap: 10px;
  position: sticky;
  top: 0;
  z-index: 10;

  @media (max-width: 375px) {
    justify-content: center;
    padding: 8px 10px;
  }
}

.top-bar .submitted,
.top-bar .countdown {
  color: #333;
  font-size: 14px;

  @media (max-width: 375px) {
    font-size: 12px;
  }
}

.top-bar .count,
.top-bar .time {
  color: #e63946;
  font-weight: bold;
}

.title-wrapper {
  display: flex;
  align-items: center;
  min-width: 150px;

  .line {
    flex: 1;
    height: 1px;
    background-color: #ccc;
    margin: 0 8px;

    @media (min-width: 1024px) {
      margin: 0 12px;
    }
  }

  .title {
    font-size: 18px;
    font-weight: bold;
    color: #e63946;

    @media (min-width: 1024px) {
      font-size: 20px;
    }
  }
}

// 卡片容器
.card-container {
  flex: 1;
  overflow-y: auto;
  border-radius: 8px;
  height: 100%;

  &::-webkit-scrollbar {
    width: 6px;
  }
  &::-webkit-scrollbar-track {
    background: transparent;
  }
  &::-webkit-scrollbar-thumb {
    background-color: rgba(220, 220, 220, 0.5);
    border-radius: 3px;
  }
  &::-webkit-scrollbar-thumb:hover {
    background-color: rgba(200, 200, 200, 0.6);
  }
  &::-webkit-scrollbar-button {
    display: none;
  }
  &::-webkit-scrollbar-corner {
    background: transparent;
  }
}

// 卡片网格
.card-grid {
  padding: 20px;
  border-radius: 10px;
  background-color: #ffffff;
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);

  @media (min-width: 375px) {
    grid-template-columns: repeat(2, 1fr);
  }

  @media (min-width: 480px) {
    grid-template-columns: repeat(3, 1fr);
  }

  @media (min-width: 768px) {
    grid-template-columns: repeat(4, 1fr);
    gap: 18px;
  }

  @media (min-width: 1024px) {
    grid-template-columns: repeat(5, 1fr);
    gap: 20px;
  }
}

// 无数据提示
.empty-tip {
  grid-column: 1 / -1;
  text-align: center;
  padding: 50px 0;
  color: #999;
  font-size: 16px;
}

// 单个反馈卡片（增加点击指针样式）
.feedback-card {
  border-radius: 10px;
  width: 100%;
  background-color: #f1f5f6;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 15px 0;
  cursor: pointer;
  transition: box-shadow 0.3s ease;

  &:hover {
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
  }
}

// 卡片主图
.feedback-card .main-img {
  width: 85%;
  height: 100px;
  object-fit: cover;
  border-radius: 12px;
  padding: 8px;

  @media (min-width: 1024px) {
    height: 120px;
    padding: 2px;
    border-radius: 12px;
  }
}

// 卡片子图容器
.feedback-card .sub-imgs {
  display: flex;
  gap: 4px;
  padding: 0 10px;

  @media (min-width: 1024px) {
    gap: 10px;
  }
}

// 卡片子图
.feedback-card .sub-img {
  width: 35px;
  height: 25px;
  object-fit: cover;
  border-radius: 2px;

  @media (min-width: 1024px) {
    width: 40px;
    height: 30px;
  }
}

// 卡片底部信息（学号+图片数）
.feedback-card .card-footer {
  background-color: #ffffff;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  width: 18%;
  padding: 0 8px;
  font-size: 20px;
  color: #666;

  @media (min-width: 1024px) {
    font-size: 18px;
  }
}

// 详情弹框样式
.student-dialog {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 999;
  display: flex;
  justify-content: center;
  align-items: center;
}

.dialog-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
}

.dialog-content {
  position: relative;
  background-color: #ffffff;
  border-radius: 12px;
  width: 80%;
  max-width: 800px;
  padding: 20px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.dialog-header h3 {
  font-size: 18px;
  color: #333;
}

.dialog-header .close-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #999;
  font-size: 20px;
}

.dialog-body .item-group {
  margin-bottom: 20px;
}

.dialog-body .label {
  display: inline-block;
  width: 100px;
  color: #e63946;
  font-weight: bold;
  margin-right: 30px;
}

.dialog-body .value {
  color: #333;
  font-size: 16px;
}

.dialog-body .images-group {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  flex-wrap: wrap;
}

.dialog-body .ai-img {
  width: 180px;
  height: 120px;
  object-fit: cover;
  border-radius: 8px;
}

.dialog-footer {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.dialog-footer .close-button {
  background-color: #e63946;
  color: #ffffff;
  border: none;
  padding: 10px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s ease;

  &:hover {
    background-color: #c41c2a;
  }
}

// 冗余样式清理
.content-divider,
.content-image,
.book-card {
  display: none;
}

// 适配小屏幕内边距
@media (max-width: 375px) {
  .main-content {
    padding: 12px;
  }
}
</style>
